/*
 * Copyright 2011 myTDev.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mytdev.util.properties.formatters.impl;

import com.mytdev.util.properties.formatters.Formatter;
import com.mytdev.util.properties.formatters.FormatterProvider;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;

/**
 *
 * @author Yann D'Isanto
 */
public class DefaultFormatterProvider implements FormatterProvider {

    /**
     * The formatters.
     */
    private final Map<Class<?>, Formatter<?>> formatters = new HashMap<Class<?>, Formatter<?>>();

    /**
     * Returns the formatter associated with the specified type.
     *
     * @param type the type.
     * @return a formatter instance or null if no formatter is associated with
     * the specified type.
     */
    @SuppressWarnings("unchecked")
    public <T> Formatter<T> getFormatter(Class<T> type) {
        return (Formatter<T>) formatters.get(type);
    }

    /**
     * Associates the specified formatter with the specified type.
     *
     * @param type the type, must be not null.
     * @param formatter the formatter. Can be null.
     * @throws NullPointerException if type is null.
     */
    public <T> void setFormatter(Class<T> type, Formatter<T> formatter) {
        if (type == null) {
            throw new NullPointerException("type is null");
        }
        formatters.put(type, formatter);
    }

    /**
     * Creates and returns a DefaultFormatterProvider filled with several
     * default formatters implementation.
     *
     * @return a DefaultFormatterProvider instance.
     */
    public static DefaultFormatterProvider getDefaultFormatterProvider() {
        DefaultFormatterProvider provider = new DefaultFormatterProvider();
        provider.setFormatter(BigDecimal.class, new BigDecimalFormatter());
        provider.setFormatter(BigInteger.class, new BigIntegerFormatter());
        provider.setFormatter(Boolean.class, new BooleanFormatter());
        provider.setFormatter(Boolean.TYPE, new BooleanFormatter());
        provider.setFormatter(Byte.class, new ByteFormatter());
        provider.setFormatter(Byte.TYPE, new ByteFormatter());
        provider.setFormatter(Character.class, new CharacterFormatter());
        provider.setFormatter(Character.TYPE, new CharacterFormatter());
        provider.setFormatter(Color.class, new ColorFormatter());
        provider.setFormatter(Dimension.class, new DimensionFormatter());
        provider.setFormatter(Double.class, new DoubleFormatter());
        provider.setFormatter(Double.TYPE, new DoubleFormatter());
        provider.setFormatter(File.class, new FileFormatter());
        provider.setFormatter(Float.class, new FloatFormatter());
        provider.setFormatter(Float.TYPE, new FloatFormatter());
        provider.setFormatter(Font.class, new FontFormatter());
        provider.setFormatter(InetAddress.class, new InetAddressFormatter());
        provider.setFormatter(Integer.class, new IntegerFormatter());
        provider.setFormatter(Integer.TYPE, new IntegerFormatter());
        provider.setFormatter(Locale.class, new LocaleFormatter());
        provider.setFormatter(Long.class, new LongFormatter());
        provider.setFormatter(Long.TYPE, new LongFormatter());
        provider.setFormatter(Pattern.class, new PatternFormatter());
        provider.setFormatter(Short.class, new ShortFormatter());
        provider.setFormatter(Short.TYPE, new ShortFormatter());
        provider.setFormatter(SimpleDateFormat.class, new SimpleDateFormatFormatter());
        provider.setFormatter(String.class, new StringFormatter());
        provider.setFormatter(URL.class, new URLFormatter());
        return provider;
    }
}
